package com.zjitc.service.imp;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;
import com.zjitc.common.Gsonal;
import com.zjitc.dao.CollectDao;
import com.zjitc.pojo.Collect;
import com.zjitc.pojo.Product;
import com.zjitc.utils.MyNumber;
import com.zjitc.vo.ForgetPasswordDemo;
import com.zjitc.vo.PageModel;
import com.zjitc.common.ServerResponse;
import com.zjitc.common.redis.RedisCache;
import com.zjitc.dao.UserDao;
import com.zjitc.pojo.User;
import com.zjitc.service.UserService;
import com.zjitc.utils.RedisAuto;
import com.zjitc.vo.UserPath;
import com.zjitc.utils.Utils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.TimeoutException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.List;

import org.springframework.web.servlet.ModelAndView;

/**
 * Create By IntelliJ IDEA
 *
 * @author: myq
 * @create-Time: 2017/11/7  15:56
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private CollectDao collectDao;
    @Autowired
    private RedisCache redis;
    @Autowired
    private ConnectionFactory factory;

    /**
     * 交换机
     */
    private final String EXCHANGE_NAME = "Exchange_BigWork";
    private final String REGISTEREMAIL = "email";
    private final String FORGETEMAIL = "forgetEmail";
    private final String PRODUCTS = "products";
    private static final String REDIS_USERS = "users";
    private static final String COLLECT = "collect";
    private static final String USER = "user";
    private final String MSG = "msg";

    @Override
    public boolean regiser(User user, String path) {
        if (redis.hashMapget(REDIS_USERS, user.getUsername()) == null) {
            if (userDao.findbyusername(user.getUsername()) == null) {
                int success = userDao.add(user);
                if (success == 1) {
                    //更新缓存
                    redis.hashset(REDIS_USERS, user.getUsername(), Gsonal.tojson(user));
                    UserPath userPath = new UserPath(user, path);
                    try (
                            Connection connection = factory.newConnection();
                            Channel channel = connection.createChannel()
                    ) {
                        channel.basicPublish
                                (EXCHANGE_NAME, REGISTEREMAIL, true, MessageProperties.PERSISTENT_TEXT_PLAIN,
                                        Gsonal.tojson(userPath).getBytes());
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (TimeoutException e) {
                        e.printStackTrace();
                    }
                }
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean active(String uid, String code) {
        User user = userDao.findbyid(uid);
        if (code.equals(user.getCode())) {
            user.setState(1);
            redis.hashset(REDIS_USERS, user.getUsername(), Gsonal.tojson(user));
            userDao.update(user);
            return true;
        }
        return false;
    }

    @Override
    public ServerResponse<User> login(String username, String password, String code,
                                      HttpSession session) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        checkredis();
        String msg = String.valueOf(session.getAttribute(MSG));
        if (msg.equalsIgnoreCase(code)) {
//          开始验证用户与密码
            password = Utils.encoderByMd5(password);
            String json = redis.hashMapget(REDIS_USERS, username);
            User user = Gsonal.fromJson(json, User.class);
            if (user == null) {
                user = userDao.findbyusername(username);
            }
            if (user != null) {
                if (user.getState() != -1) {
                    if (user.getPassword().equals(password)) {
                        session.setAttribute(USER, user);
                        return ServerResponse.createSuccess("1");
                    }
                    return ServerResponse.createSuccess("-1");
                }
                return ServerResponse.createSuccess("-2");
            }
            return ServerResponse.createSuccess("-1");
        }
        return ServerResponse.createSuccess("0");

    }

    @Override
    public User adminLogin(String username, String password) {
        checkredis();
        String json = redis.hashMapget(REDIS_USERS, username);
        User user = Gsonal.fromJson(json, User.class);
        if (user == null) {
            user = userDao.findbyusername(username);
        }
        try {
            if (user.getPassword().equals(Utils.encoderByMd5(password))) {
                int hundred = 100;
                if (user.getState() == hundred) {
                    return user;
                }
            }
            return null;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public ServerResponse<User> checkUsername(String username) {
        checkredis();
        String tojson = redis.hashMapget(REDIS_USERS, username);
        if (tojson == null) {
            if (userDao.findbyusername(username) == null) {
                return ServerResponse.createSuccess("1");
            }

        }
        return ServerResponse.createSuccess("0");
    }

    @Override
    public PageModel<User> findall(int pageid, int count) {
        List<User> users = redis.hashListGetAll(REDIS_USERS, User.class);
        if(users == null){
            users = userDao.findAll();
        }
        PageModel<User> pageModel = new PageModel<>(users, count, pageid);
        return pageModel;
    }

    @Override
    public void update(User user) {
        userDao.update(user);
        redis.hashset(REDIS_USERS,user.getUsername(),Gsonal.tojson(user));
    }

    @Override
    public User findbyuid(String uid) {
        return userDao.findbyid(uid);
    }

    @Override
    public void deluser(String uid) {
        User user = userDao.findbyid(uid);
        userDao.deluser(uid);
        redis.delHash(REDIS_USERS,user.getUsername());
//        RedisAuto.usersRedis(userDao, redis, REDIS_USERS);
    }

    @Override
    public ServerResponse checkpassword(String password, String verifypassword) {
        if (!"".equals(password)) {
            if (password.equals(verifypassword)) {
                return ServerResponse.createSuccess("1");
            } else {
                return ServerResponse.createSuccess("0");
            }
        }
        return ServerResponse.createSuccess("0");
    }

    @Override
    public void forgetSendEmail(ForgetPasswordDemo demo) {
        try (
                Connection connection = factory.newConnection();
                Channel channel = connection.createChannel()
        ) {
            channel.basicPublish(EXCHANGE_NAME, FORGETEMAIL, MessageProperties.PERSISTENT_TEXT_PLAIN,
                    Gsonal.tojson(demo).getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
    }

    @Override
    public ServerResponse forgetcheckcode(ForgetPasswordDemo demo, String code) {
        String rediscode = (String) redis.get(demo.getUsername());
        if (code.equalsIgnoreCase(rediscode)) {
            return ServerResponse.createSuccess(demo);
        }
        return ServerResponse.createError("-1");
    }

    @Override
    public String finduidByusername(String username) {
        User user = userDao.findbyusername(username);
        if (user != null) {
            return user.getUid();
        }
        return null;

    }

    @Override
    public boolean forgetResetPassword(User user) {
        checkredis();
        String  username = userDao.findusernameByuid(user.getUid());
        User redisuser = redis.hashgetObject(REDIS_USERS, username, User.class);
        if(redisuser == null){
            redisuser = userDao.findbyusername(username);
        }
        try {
            redisuser.setPassword(Utils.encoderByMd5(user.getPassword()));
            redis.hashset(REDIS_USERS, redisuser.getUsername(), Gsonal.tojson(redisuser));
            userDao.update(redisuser);
            return true;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return false;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public ServerResponse resetPassword(String username, String oldPassword, String newPassword,
                                        HttpSession session) {
        checkredis();
        User user = redis.hashgetObject(REDIS_USERS, username, User.class);
        if(user == null){
            user = userDao.findbyusername(username);
        }
        try {
            if (user.getPassword().equals(Utils.encoderByMd5(oldPassword))) {
                user.setPassword(Utils.encoderByMd5(newPassword));
                redis.hashset(REDIS_USERS, username, Gsonal.tojson(user));
                userDao.update(user);
                session.removeAttribute(USER);
                return ServerResponse.createSuccess();
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return ServerResponse.createError();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return ServerResponse.createError();
        }
        return ServerResponse.createError("旧密码错误");
    }

    @Override
    public ModelAndView searchMyCollect(HttpSession session, String page) {
        ModelAndView mv = new ModelAndView("/jsp/searchCollect");
        User user = (User) session.getAttribute(USER);
        if(user == null) {
            List<Collect> collectList = redis.hashListGetAll(COLLECT, Collect.class);
            if (collectList == null) {
                collectList = collectDao.findCollectbyuid(user.getUid());
            }
            List<Product> productList = new ArrayList<>();
            collectList.forEach(collect -> {
                Product product = redis.hashgetObject(PRODUCTS, collect.getPid(), Product.class);
                productList.add(product);
            });
            PageModel pageModel = new PageModel(productList, Integer.parseInt(page));
            mv.addObject("pagemodel", pageModel);
        }else {
            mv.setViewName("jsp/login");
        }
        return mv;
    }


    private void checkredis() {
        if (!redis.exists(REDIS_USERS)) {
            RedisAuto.usersRedis(userDao, redis, REDIS_USERS);
        }
    }


}
